﻿using BJ.AuthDomain.Commands;
using BJ.AuthDomain.IService;
using BJ.AuthEntity.Models;
using Mapster;
using Syspetro.Core.AppDeal;
using Syspetro.Core.CommandBus;
using Syspetro.Core.GoogleAuth;
using Syspetro.Core.GoogleAuth.Google2;
using Syspetro.Deploy.Managers;
using Syspetro.DepRedis;
using System;
using System.Threading.Tasks;

namespace BJ.AuthDomain.Service
{
    public class AdminGoogleAuthService : IAdminGoogleAuthService
    {
        readonly IFreeSql _freeSql;
        readonly IAuthorizationManager _authorization;
        readonly ICommandBus _command;
        public AdminGoogleAuthService(IFreeSql freeSql, IAuthorizationManager authorization, ICommandBus command)
        {
            _freeSql = freeSql;
            _authorization = authorization;
            _command = command;
        }
        public async Task<SpActionResult<bool>> Validate(string code)
        {
            return await Task.Run(() =>
            {
                var vref = _command.Send(new GoogleVerifyCommand { Captcha = code, UserId = _authorization.GetUserId, IsAdmin = _authorization.IsAdmin });
                if (vref.Success) return new SpActionResult<bool>(true);
                else return new SpActionResult<bool> { Success = false, Msg = vref.Msg };
            });
        }
        public async Task<SpActionResult<GoogleBindingModel>> GenerateBind(Guid uid)
        {
            var user = await _freeSql.Select<AdminUser>().Where(t => t.Id == uid).FirstAsync();
            if (user == null)
                return new SpActionResult<GoogleBindingModel> { Success = false, Msg = "异常用户" };

            //if (!string.IsNullOrEmpty(user.Enable2FA))
            //    return new SpActionResult<GoogleBindingModel> { Success = false, Msg = "已绑定谷歌验证" };
            GoogleAuthenticatorProvider2 google = new();
            var binding = google.Generate(user.Name);
            user.Enable2FA = binding.Salt;
            var _user = new AdminUser { Id = user.Id, Enable2FA = user.Enable2FA };
            if (await _freeSql.Update<AdminUser>().SetSource(_user).UpdateColumns(t => t.Enable2FA).ExecuteAffrowsAsync() > 0)
            {
                return new SpActionResult<GoogleBindingModel>(binding.Adapt<GoogleBindingModel>());
            }
            return new SpActionResult<GoogleBindingModel> { Success = false, Msg = "绑定失败" };
        }
        public async Task<SpActionResult<GoogleBindingModel>> Generate()
        {
            var uid = _authorization.GetUserId;
            var user = await _freeSql.Select<AdminUser>().Where(t => t.Id == uid).FirstAsync();

            if (user == null)
                return new SpActionResult<GoogleBindingModel> { Success = false, Msg = "异常用户" };

            if (!string.IsNullOrEmpty(user.Enable2FA))
                return new SpActionResult<GoogleBindingModel> { Success = false, Msg = "已绑定谷歌验证" };

            RedisHelper redis = new("GoogleBinding");
            var binding = redis.CacheGet<GoogleAuthenticatorBinding2>(user.Id.ToString());
            if (binding == null)
            {
                GoogleAuthenticatorProvider2 google = new();
                binding = google.Generate(user.Name);
                redis.CacheSet(user.Id.ToString(), binding);
            }
            return new SpActionResult<GoogleBindingModel>(binding.Adapt<GoogleBindingModel>());
        }
        public async Task<bool> IsSetGoogle(Guid uid)
        {
            return await _freeSql.Select<AdminUser>().Where(t => t.Id == uid).Where(t => t.Enable2FA != string.Empty).AnyAsync();
        }
        public async Task<SpActionResult<bool>> Bind(string Captcha)
        {
            var authBind = _authorization.GetUserId;
            var user = await _freeSql.Select<AdminUser>().Where(t => t.Id == authBind).FirstAsync();
            if (user == null)
                return new SpActionResult<bool> { Success = false, Msg = "异常用户" };
            if (!string.IsNullOrEmpty(user.Enable2FA))
                return new SpActionResult<bool> { Success = false, Msg = "已绑定谷歌验证" };
            RedisHelper redis = new("GoogleBinding");

            var binding = redis.CacheGet<GoogleAuthenticatorBinding2>(user.Id.ToString());
            if (binding == null)
                return new SpActionResult<bool> { Success = false, Msg = "绑定信息已失效" };

            GoogleAuthenticatorProvider2 google = new();
            if (!google.Validate(binding.Salt, Captcha))
                return new SpActionResult<bool> { Success = false, Msg = "验证码错误" };
            user.Enable2FA = binding.Salt;

            var _user = new AdminUser { Id = user.Id, Enable2FA = user.Enable2FA };
            if (await _freeSql.Update<AdminUser>().SetSource(_user).UpdateColumns(t => t.Enable2FA).ExecuteAffrowsAsync() > 0)
            {
                return new SpActionResult<bool>(true);
            }
            return new SpActionResult<bool> { Success = false, Msg = "绑定失败" };
        }
    }
}
